#!/usr/local/python/bin/python
# coding=utf-8
__author__ = 'Junjie.M'

import datetime
from time import strftime,localtime
import time
import calendar


_year = strftime("%Y",localtime())
_mon = strftime("%m",localtime())
_day = strftime("%d",localtime())
_hour = strftime("%H",localtime())
_min = strftime("%M",localtime())
_sec = strftime("%S",localtime())
START = 0
END = 1

EARLY_MONTH = "1"
MID_MONTH = "2"
LATE_MONTH = "3"



FIRST_QUARTER = "1"
SECOND_QUARTER ="2"
THIRD_QUARTER = "3"
FOURTH_QUARTER = "4"

TIME_FORMATRE = '%Y-%m-%d %I:%M:%S'
TIME_FORMATRE_YYMMDD = '%Y%m%d'
TIME_FORMATRE_YY_MM_DD = '%Y-%m-%d'
class DateUtils(object):
    @staticmethod
    def time2format(strTime):
        '''
        格式转化 TIME_FORMATRE ------  TIME_FORMATRE_YYMMDD
        :param strTime:
        :return:
        '''
        return strTime[0:4]+strTime[5:7]+strTime[9:11]
    @staticmethod
    def getFirstDateOfNow():
        '''
        获取当前日期对应年初
        :return:
        '''
        return DateUtils.getFirstDateOfYear(int(_year))
    @staticmethod
    def getFirstDateOfAutNow():
        '''
        当前日期对应季初
        :return:
        '''

        return DateUtils.getFirstDateOfAut(int(_year),int(_mon))
    @staticmethod
    def getFirstDateOfMonNow():
        '''
        当前日期对应季初
        :return:
        '''

        return DateUtils.getFirstDateOfThisMonth(int(_year),int(_mon))
    @staticmethod
    def getLastDateOfAutNow():
        '''
        当前日期对应季末
        :return:
        '''
        return DateUtils.getLastDateOfAut(int(_year),int(_mon))
    @staticmethod
    def getLastDateOfAut(intYear,intMonth):
        '''
        当前日期对应季末
        :param intYear:
        :param intMonth:
        :return:
        '''
        result=str(intYear)+"-"
        aut = DateUtils().whichQuartert(int(intMonth))
        if aut == FIRST_QUARTER:
            result=result+"03-"+"31"
        if aut == SECOND_QUARTER:
            result=result+"06-"+"30"
        if aut == THIRD_QUARTER:
            result=result+"09-"+"30"
        if aut == FOURTH_QUARTER:
            result=result+"12-"+"31"
        return result
    @staticmethod
    def getFirstDateOfAut(intYear,intMonth):
        '''
        当前日期对应季初
        :param intYear:
        :param intMonth:
        :return:
        '''
        result=str(intYear)+"-"
        aut = DateUtils().whichQuartert(int(intMonth))
        if aut == FIRST_QUARTER:
            result=result+"01"+"01"
        if aut == SECOND_QUARTER:
            result=result+"04"+"01"
        if aut == THIRD_QUARTER:
            result=result+"07"+"01"
        if aut == FOURTH_QUARTER:
            result=result+"10"+"01"
        return result
    @staticmethod
    def getFirstDateOfYear(intYear):
        '''
        获取当前日期对应年初
        :param intYear:
        :return:
        '''
        arr = (str(intYear),'01','01')
        return "".join("%s" %i for i in arr)
    @staticmethod
    def getLastDateOfNow():
        '''
         当前日期对应年末
        :return:
        '''
        return DateUtils.getLastDateOfYear(int(_year))
    @staticmethod
    def getLastDateOfYear(intYear):
        '''
        当前日期对应年末
        :param intYear:
        :return:
        '''
        arr = (str(intYear),'12','31')
        return "".join("%s" %i for i in arr)
    @staticmethod
    def getFirstDateOfThisMonth():
        '''
        获取当月的第一天
        :return:
        '''
        return DateUtils.getFirstDateOfMonth(_year,_mon)
    @staticmethod
    def getLastDateOfThisMonth():
        '''
        获取当月的月末
        :return:
        '''
        return DateUtils.getLastDateOfMonth(int(_year),int(_mon))
    @staticmethod
    def getLastDateOfMonth(year,mon):
        '''
        获取某个月的月末
        :param year:
        :param mon:
        :return:
        '''
        days=DateUtils.getIntDaysByMonth(year,mon)
        if int(mon)<10:
            mon = "0"+str(int(mon))
        arr = (year,mon,days)
        return "".join("%s" %i for i in arr)
    @staticmethod
    def getFirstDateOfMonth(year,mon):
        '''
        获取某个月的第一天
        :param year:
        :param mon:
        :return:
        '''
        days="01"
        if int(mon)<10:
            mon = "0"+str(int(mon))
        arr = (year,mon,days)
        return "".join("%s" %i for i in arr)
    @staticmethod
    def getSystemTime():
        '''
        获取系统时间
        :return:
        '''
        return time.strftime(TIME_FORMATRE, time.localtime(time.time()))
    @staticmethod
    def getIntDaysByMonth(intYear,intMonth):
        '''
        获取某个月有多少天
        :param intYear:
        :param intMonth:
        :return:
        '''
        intDaysByMonth = 31
        smallMonth = (4,6,9,11)
        for i in smallMonth:
            if intMonth == i:
                intDaysByMonth = 30
                break
        if DateUtils().isDoubleYear(intYear) and intMonth==2:
            intDaysByMonth=29
        if (DateUtils().isDoubleYear(intYear)==False) and intMonth==2:
            intDaysByMonth=28
        return intDaysByMonth

    def whichQuartert(self,intMonth):
        '''
        判断是哪个季度
        :param intMonth:
        :return:
        '''
        result=""
        if intMonth in (1,2,3):
            result = FIRST_QUARTER
        if intMonth in (4,5,6):
            result = SECOND_QUARTER
        if intMonth in (7,8,9):
            result = THIRD_QUARTER
        if intMonth in (10,11,12):
            result = FOURTH_QUARTER
        return result
    def isDoubleYear(self,intYear):
        '''
        判断是否是闰年
        :param intYear:
        :return:
        '''
        if (intYear%4 == 0 and intYear%100 !=0) or (intYear%400 ==0):
            return True
        else:
            return False
    @staticmethod
    def setDateBytime(intDay):
        '''
        获取和当前时间相差若干天的时间
        :param intDay:
        :return:
        '''
        result = datetime.datetime.now() - datetime.timedelta(days=intDay)
        return result.strftime(TIME_FORMATRE)
    @staticmethod
    def getLongDate(givenDate):
        '''
        将字符串日期转化成10位YYYY-MM-DD日期
        :param givenDate:
        :return:
        '''
        if len(givenDate)!=8:
            return None
        dateGiven=givenDate[0:4] + '-' + givenDate[4:6] + '-' + givenDate[6:8]
        return dateGiven
    @staticmethod
    def getShortDate(givenDate):
        '''
        将字符串日期YYYY-MM-DD转化成10位YYYYMMDD日期
        :param givenDate:
        :return:
        '''
        return givenDate.replace('-','')
    @staticmethod
    def getDateTime(givenDate):
        '''
        将字符串日期转化成datetime日期
        :param givenDate:
        :return:
        '''
        givenDate=givenDate.replace('-','')
        dateGiven = datetime.datetime(int(givenDate[0:4]),int(givenDate[4:6]),int(givenDate[6:8]))
        return dateGiven
    @staticmethod
    def getDateByCount(givenDate,dayCount):
        '''
        当前日期前几天或后几天日期  当前日期为字符串格式为20150411
        :param givenDate:
        :return:  返回为字符串格式日期
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        result = dateGiven+datetime.timedelta(days=dayCount)
        return result.strftime(TIME_FORMATRE_YYMMDD)
    @staticmethod
    def getNextDate(givenDate):
        '''
        当前日期下一日  当前日期为字符串格式为20150411
        :param givenDate:
        :return:  返回为字符串格式日期
        '''
        return DateUtils.getDateByCount(givenDate,1)
    @staticmethod
    def getPreDate(givenDate):
        '''
        当前日期上一日 当前日期为字符串格式为20150411
        :param givenDate:
        :return:  返回为字符串格式日期
        '''
        return DateUtils.getDateByCount(givenDate,-1)
    @staticmethod
    def getWeekDayByType(givenDate,type):
        '''
         当前日期对应周几（周一） 当前日期为字符串格式为20150411
        :param givenDate:
        :param type:
        :return:
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        if dateGiven.weekday() != type:
            dayCounts = type - dateGiven.weekday()
            dateGiven += datetime.timedelta(days =dayCounts)
        return dateGiven.strftime(TIME_FORMATRE_YYMMDD)
    @staticmethod
    def getWeekStart(givenDate):
        '''
         当前日期对应周初（周一） 当前日期为字符串格式为20150411
        :param givenDate:
        :return:返回为字符串格式日期
        '''
        return DateUtils.getWeekDayByType(givenDate,calendar.MONDAY)
    @staticmethod
    def getWeekEnd(givenDate):
        '''
        当前日期对应周末（周六） 当前日期为字符串格式为20150411
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        return DateUtils.getWeekDayByType(givenDate,calendar.SATURDAY)
    @staticmethod
    def getMonthStart(givenDate):
       '''
       当前日期对应月初
       :param givenDate:
       :return:返回为字符串格式日期20150411
       '''
       dateGiven = DateUtils.getDateTime(givenDate)
       return DateUtils.getShortDate(DateUtils.getFirstDateOfMonth(dateGiven.year,dateGiven.month))

    @staticmethod
    def getPrMon(givenDate,countDay):
        '''

        :param givenDate:
        :param countDay:
        :return:
        '''
        dateGiven = DateUtils.getDateTime(givenDate)

        result = (dateGiven.replace(day = countDay) - datetime.timedelta(1)).replace(day = countDay)
        return result.strftime(TIME_FORMATRE_YYMMDD);
    @staticmethod
    def getMonthEnd(givenDate):
       '''
       当前日期对应月末
       :param givenDate:
       :return:返回为字符串格式日期20150411
       '''
       dateGiven = DateUtils.getDateTime(givenDate)
       return DateUtils.getShortDate(DateUtils.getLastDateOfMonth(dateGiven.year,dateGiven.month))
    @staticmethod
    def getPrMonStart(givenDate):
        '''
        当前日期上月初
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        return DateUtils.getPrMon(givenDate,1)
    @staticmethod
    def getPrMonEnd(givenDate):
        '''
        当前日期上月末
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        dateGiven = DateUtils.getDateTime(DateUtils.getPrMon(givenDate,1))
        days=DateUtils.getIntDaysByMonth(dateGiven.year,dateGiven.month)
        return DateUtils.getPrMon(DateUtils.getPrMon(givenDate,1),int(days))
    @staticmethod
    def getQuarterStart(givenDate):
        '''
        当前日期对应季初
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        return DateUtils.getShortDate(DateUtils.getFirstDateOfAut(dateGiven.year,dateGiven.month))
    @staticmethod
    def getQuarterEnd(givenDate):
        '''
        当前日期对应季末
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        return DateUtils.getShortDate(DateUtils.getLastDateOfAut(dateGiven.year,dateGiven.month))
    @staticmethod
    def getYearStart(givenDate):
        '''
        当前日期对应年初
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        return DateUtils.getFirstDateOfYear(dateGiven.year)
    @staticmethod
    def getYearEnd(givenDate):
        '''
       当前日期对应年末
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        return DateUtils.getLastDateOfYear(dateGiven.year)

    @staticmethod
    def getTendStart(givenDate):
        '''
        当前日期对应旬初
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        return DateUtils.getTendDate(givenDate,START)
    @staticmethod
    def getTendEnd(givenDate):
        '''
        当前日期对应旬末
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        return DateUtils.getTendDate(givenDate,END)
    @staticmethod
    def getTendDate(givenDate,getType):
        '''

        :param givenDate:
        :param getType:
        :return:
        '''
        result = 1
        mon=""
        resultNew=""
        dateGiven = DateUtils.getDateTime(givenDate)
        tendType = DateUtils.getTendType(givenDate)
        if getType == START:
            if int(tendType)==1:
                result = 1
            elif int(tendType)==2:
                result = 11
            elif int(tendType)==3:
                result = 21
        elif getType == END:
            if int(tendType)==1:
                result = 10
            elif int(tendType)==2:
                result = 20
            elif int(tendType)==3:
                result = int(DateUtils.getIntDaysByMonth(dateGiven.year,dateGiven.month))
        if int(dateGiven.month)<10:
            mon = "0"+str(int(dateGiven.month))
        else:
            mon=str(dateGiven.month)
        resultNew = str(result)
        if int(result)<10:
            resultNew = "0"+resultNew
        return str(dateGiven.year)+str(mon)+resultNew
    @staticmethod
    def getTendType(givenDate):
        '''
        当前日期对应旬
        :param givenDate:
        :return:
        '''
        result=""
        dateGiven = DateUtils.getDateTime(givenDate)
        day = dateGiven.day
        arrTendS=(1,2,3,4,5,6,7,8,9,10)
        arrTendM=(11,12,13,14,15,16,17,18,19,20)
        if day in arrTendS:
            result = EARLY_MONTH
        elif day in arrTendM:
            result = MID_MONTH
        else:
            result = LATE_MONTH
        return result
    @staticmethod
    def getPrQtrEnd(givenDate):
        '''
        当前日期上季末
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        aut = DateUtils().whichQuartert(dateGiven.month)
        if int(aut) == int(FIRST_QUARTER):
            return datetime.datetime(dateGiven.year-1,12,31).strftime(TIME_FORMATRE_YYMMDD)
        elif int(aut) == int(SECOND_QUARTER):
             return datetime.datetime(dateGiven.year,3,31).strftime(TIME_FORMATRE_YYMMDD)
        elif int(aut) == int(THIRD_QUARTER):
             return datetime.datetime(dateGiven.year,6,30).strftime(TIME_FORMATRE_YYMMDD)
        elif int(aut) == int(FOURTH_QUARTER):
             return datetime.datetime(dateGiven.year,9,30).strftime(TIME_FORMATRE_YYMMDD)
    @staticmethod
    def getPriSDate(givenDate):
        '''
        当前日期去年同期
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        year = dateGiven.year - 1
        return   datetime.datetime(year,dateGiven.month,dateGiven.day).strftime(TIME_FORMATRE_YYMMDD)
    @staticmethod
    def getHalfyearStart(givenDate):
        '''
        当前日期对应半年初
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        return   datetime.datetime(dateGiven.year,7,1).strftime(TIME_FORMATRE_YYMMDD)
    @staticmethod
    def getPreSixMonthDate(givenDate):
        '''
        当前日期对应半年前日期
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        mon = dateGiven.month
        year = dateGiven.year
        if mon > 6:
            mon = mon - 6
        else:
            mon = 6 + mon
            year = year -  1
        return   datetime.datetime(year,mon,dateGiven.day).strftime(TIME_FORMATRE_YY_MM_DD)
    @staticmethod
    def getHalfyearEnd(givenDate):
        '''
        当前日期对应半年末
        :param givenDate:
        :return:返回为字符串格式日期20150411
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        return   datetime.datetime(dateGiven.year,6,30).strftime(TIME_FORMATRE_YYMMDD)

    @staticmethod
    def getNowYMDDate():
        '''
        获取当前日期YYYYMMDD
        :return:返回为字符串格式日期20150411
        '''
        return time.strftime(TIME_FORMATRE_YYMMDD)
    @staticmethod
    def getLastDateAddMonths(givenDate,addMonths):
        '''
        获取日期N月前或月后的月末日期
        :return:返回为字符串格式日期20150411
        '''
        dateGiven = DateUtils.getDateTime(givenDate)
        mon = dateGiven.month
        year = dateGiven.year
        totalmonth=mon+addMonths
        if(addMonths>=0):
            if(totalmonth>=12):
                return DateUtils.getLastDateOfMonth(year,totalmonth)
            else:
                i=totalmonth/12
                j=totalmonth%12
                if (j==0):
                    i-=1
                    j=12
                year +=i
                return DateUtils.getLastDateOfMonth(year,j)
        else:
            if ((totalmonth>0) and (totalmonth<12)):
                return DateUtils.getLastDateOfMonth(year,totalmonth)
            else:
                i=totalmonth/12
                j=totalmonth%12
                if (j==0):
                    i-=1
                    j=12
                year +=i
                return DateUtils.getLastDateOfMonth(year,j)

    @staticmethod
    def isDate(str):
        '''
        判断字符串是否是日期类型
        :param givenDate:
        :return:返回True 成功 or Flase 失败
        '''
        try:
            length = len(str)
            if length == 8:
                time.strptime(str,"%Y%m%d")
                return str
            elif length == 10:
                str = DateUtils.time2format(str)
                time.strptime(str,"%Y%m%d")
                return str
        except:
            return None

#主程序
if __name__ == "__main__":
    print DateUtils.getLastDateAddMonths('20150909',-5)